package com.example.carbonbackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.carbonbackend.common.BaseResponse;
import com.example.carbonbackend.common.ResultUtils;
import com.example.carbonbackend.constant.CommonConstant;
import com.example.carbonbackend.model.dto.*;
import com.example.carbonbackend.model.dto.emission.CarbonEmissionQueryRequest;
import com.example.carbonbackend.model.entity.CarbonEmission;
import com.example.carbonbackend.model.entity.Company;
import com.example.carbonbackend.model.entity.User;
import com.example.carbonbackend.model.vo.CarbonEmissionVO;
import com.example.carbonbackend.service.CarbonEmissionService;
import com.example.carbonbackend.mapper.CarbonEmissionMapper;
import com.example.carbonbackend.service.CompanyService;
import com.example.carbonbackend.service.UserService;
import com.example.carbonbackend.utils.SqlUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
* @author 25103
* @description 针对表【carbonemission(碳排放表)】的数据库操作Service实现
* @createDate 2024-03-18 17:35:41
*/
@Service
public class CarbonEmissionServiceImpl extends ServiceImpl<CarbonEmissionMapper, CarbonEmission>
    implements CarbonEmissionService {
    
    @Resource
    CompanyService companyService;
    @Resource
    UserService userService;

    /**
     * 查找碳排放数据
     */
    @Override
    public String search(String keyword,int yaer){
        //1. 根据公司名称查找公司id
        LambdaQueryWrapper<Company> companyLambdaQueryWrapper=new LambdaQueryWrapper<>();
        companyLambdaQueryWrapper.eq(Company::getCompanyName,keyword);
        Long id=companyService.getOne(companyLambdaQueryWrapper).getId();
        //2.根据公司id查找公司碳排放信息
        LambdaQueryWrapper<CarbonEmission> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(CarbonEmission::getCompanyId,id).eq(CarbonEmission::getYear,yaer);
        String url= getOne(queryWrapper).getUrl();
        return url;
    }
    @Override
    public BaseResponse<String> accountForEG(EGCarbonemissionDto egCarbonemissionDto) throws IOException {
        Double eBurn=0.0;
        Double eDesul=0.0;
        Double eElec=0.0;
        Double e=0.0;
        //1.计算化石燃烧的碳排放数据
        for(FossilFuelDto fossilFuel:egCarbonemissionDto.getFossilFuelList()){
            eBurn+=fossilFuel.getFC()* fossilFuel.getNCV()*1e-6* fossilFuel.getCC()
                    * fossilFuel.getOF()*44.0/12.0;
        }
        //2.计算脱硫过程的碳排放数据
        for(DesulfurizerDto desulfurizer:egCarbonemissionDto.getDesulfurizerList()){
            eDesul+=desulfurizer.getI()*desulfurizer.getEFkt();
        }
        //3.计算电力产生的碳排放数据
        eElec= egCarbonemissionDto.getEFE()* egCarbonemissionDto.getADE();
        e=eBurn+eDesul+eElec;
        egCarbonemissionDto.setEBurn(eBurn);
        egCarbonemissionDto.setEDesul(eDesul);
        egCarbonemissionDto.setEElec(eElec);
        egCarbonemissionDto.setE(e);
        List<EGReport> reports=new ArrayList<EGReport>();
        reports.add(new EGReport("企业二氧化碳排放总量（tCO2）",e));
        reports.add(new EGReport("化石燃料燃烧排放量（tCO2）",eBurn));
        reports.add(new EGReport("脱硫过程排放量（tCO2））",eDesul));
        reports.add(new EGReport("净购入使用的电力排放量（tCO2）",eElec));
        //4.生成排放文件
        String url= null;

        url = WordWriter.createEGWordDocument(egCarbonemissionDto.getCompanyName(),
                egCarbonemissionDto.getYear(),e,eBurn,eDesul,eElec );

        //5.将碳核算数据写入数据库
        LambdaQueryWrapper<Company> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Company::getCompanyName,egCarbonemissionDto.getCompanyName());
        Company company= companyService.getOne(queryWrapper);
        CarbonEmission carbonemission = new CarbonEmission();
        carbonemission.setCompanyId(company.getId());
        carbonemission.setEmission(e);
        Long l= 1L;
        carbonemission.setUrl(url);
        //todo year
        carbonemission.setYear(2024);
        save(carbonemission);
        return ResultUtils.success("上传成功");
    }
    /**
     * 接收表现层传入的碳排放数据
     */
    @Override
    public BaseResponse<String> inputEG(String name, String year, File file) throws IOException {
        // com.example.carbonbackend.service.CarbonemissionService1 carbonemissionService=new CarbonemissionService1Impl();
        EGCarbonemissionDto egCarbonemissionDto= null;
        //1.检查文件格式并读取碳核算数据
        try {
            egCarbonemissionDto = WordReader.eGAssignment(name,year,file);
        } catch (IllegalStateException ex) {
            throw new IllegalStateException("上传格式错误，请重新上传");
        }
        //2.返回碳核算结果
        return  accountForEG(egCarbonemissionDto);
    }

    /**
     * 计算碳排放数据（电网企业）
     */
    @Override
    public BaseResponse<String> accountForEU(EUCarbonemissionDto euCarbonemissionDto) throws IOException {

        //1.计算碳排放量
        Double eSf6=0.0;
        Double eTran;
        Double devSum=0.0;
        for(RepairEquipmentDto repairEquipment: euCarbonemissionDto.getRepairList()){
            devSum+=repairEquipment.getCapacity()-repairEquipment.getRecovery();
        }
        for(RetiredEquipmentDto retiredEquipment: euCarbonemissionDto.getRetireList()){
            devSum+=retiredEquipment.getCapacity()-retiredEquipment.getRecovery();
        }
        eSf6=devSum*euCarbonemissionDto.getGWP()*0.001;
        Double eLSupply=euCarbonemissionDto.getELIn()+euCarbonemissionDto.getELOut()+euCarbonemissionDto.getELSurf();
        Double eLSell=euCarbonemissionDto.getELSell();
        Double ef=euCarbonemissionDto.getEF();
        eTran=(eLSupply-eLSell)*ef;
        euCarbonemissionDto.setETran(eTran);
        euCarbonemissionDto.setESf6(eSf6);
        euCarbonemissionDto.setE(eTran+eSf6);

        //2.碳排放量写入碳排放报告，并生成url
        String url = WordWriter.createEUWordDocument(euCarbonemissionDto.getCompanyName(),
                euCarbonemissionDto.getYear(),eTran+eSf6,eTran,eSf6);
        System.out.println(url);
        LambdaQueryWrapper<Company> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Company::getCompanyName,euCarbonemissionDto.getCompanyName());
        Long companyId= companyService.getOne(queryWrapper).getId();
        CarbonEmission carbonemission = new CarbonEmission();
        carbonemission.setEmission(eTran+eSf6);
        carbonemission.setUrl(url);
        carbonemission.setYear(Integer.parseInt(euCarbonemissionDto.getYear()));
        carbonemission.setCompanyId(companyId);
        save(carbonemission);
        return ResultUtils.success("上传成功");
    }

    @Override
    public QueryWrapper<CarbonEmission> getQueryWrapper(CarbonEmissionQueryRequest carbonEmissionQueryRequest) {
        QueryWrapper<CarbonEmission> queryWrapper = new QueryWrapper<>();
        if (carbonEmissionQueryRequest == null) {
            return queryWrapper;
        }
        Long id = carbonEmissionQueryRequest.getId();
        String blockchainId = carbonEmissionQueryRequest.getBlockchainId();
        Long companyId = carbonEmissionQueryRequest.getCompanyId();
 
        Integer emissionStatus = carbonEmissionQueryRequest.getEmissionStatus();
        Double emission = carbonEmissionQueryRequest.getEmission();
        Integer year = carbonEmissionQueryRequest.getYear();
       
        String sortField = carbonEmissionQueryRequest.getSortField();
        String sortOrder = carbonEmissionQueryRequest.getSortOrder();
        

        // 拼接查询条件
        queryWrapper.ne(ObjectUtils.isNotEmpty(blockchainId), "blockchain_id", blockchainId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(companyId), "company_id", companyId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(emissionStatus), "emission_status", emissionStatus);
        queryWrapper.eq("is_delete", false);
        queryWrapper.eq(ObjectUtils.isNotEmpty(year), "emission_year", year);
        queryWrapper.eq(ObjectUtils.isNotEmpty(emission), "emission", emission);
        
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;

    }

    @Override
    public CarbonEmissionVO getCarbonEmissionVO(CarbonEmission carbonEmission, HttpServletRequest request) {
        if (carbonEmission == null) {
            return null;
        }

        CarbonEmissionVO carbonEmissionVO = new CarbonEmissionVO();
        BeanUtils.copyProperties(carbonEmission, carbonEmissionVO);

        return carbonEmissionVO;
        
 
    }

    @Override
    public Page<CarbonEmissionVO> getCarbonEmissionVOPage(Page<CarbonEmission> carbonEmissionPage, HttpServletRequest request) {
        List<CarbonEmission> CarbonEmissionList = carbonEmissionPage.getRecords();
        Page<CarbonEmissionVO> carbonEmissionVOPage = new Page<>(carbonEmissionPage.getCurrent(), carbonEmissionPage.getSize(), carbonEmissionPage.getTotal());

        if (CollectionUtils.isEmpty(CarbonEmissionList)) {
            return carbonEmissionVOPage;
        }
        User loginUser = userService.getLoginUser(request);

//        // 1.查询关联用户信息
//        User user = userService.getById(loginUser.getId());
//        if(user==null){
//            throw new IllegalArgumentException(String.valueOf(ErrorCode.NOT_LOGIN_ERROR));
//        }
//
        // 2.筛选出用户本身的交易记录
        List<CarbonEmissionVO> collect = CarbonEmissionList.stream().map(carbonEmission -> {

            CarbonEmissionVO carbonEmissionVO = new CarbonEmissionVO();

            BeanUtils.copyProperties(carbonEmission,carbonEmissionVO);

           return carbonEmissionVO;

        }).collect(Collectors.toList());

        carbonEmissionVOPage.setRecords(collect);

        return carbonEmissionVOPage;
        
    }

    /**
     * 接收表现层传入的碳排放数据(电网企业)
     */
    @Override
    public BaseResponse<String> inputEU(String name, String year, File file) throws IOException {
        EUCarbonemissionDto euCarbonemissionDto=WordReader.eUAssignment(name,year,file);
        return accountForEU(euCarbonemissionDto);
    }


}




